package com.xmut.mall.auth.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.xmut.mall.auth.myenum.AuthEnum;
import com.xmut.mall.auth.service.AuthService;
import com.xmut.mall.auth.utils.JWTUtils;
import com.xmut.mall.auth.utils.RespBean;
import com.xmut.mall.auth.vo.JwtAuthCheckVo;
import com.xmut.mall.auth.vo.JwtTokenRenewalVo;
import com.xmut.mall.auth.vo.MemberVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;

@Service
@Slf4j
public class AuthServiceImpl implements AuthService {

    @Autowired
    private HttpServletRequest request;

    /**
     * 校验jwt权限
     *
     * @param vo
     * @return
     */
    @Override
    public RespBean JwtAuthCheck(JwtAuthCheckVo vo) {
        log.info("开始校验Token");
        if (JWTUtils.checkIsExpires(vo.getAccessToken())) {
            // 如果accesstoken过期 开始验证refreshToken是否过期
            if (JWTUtils.checkIsExpires(vo.getRefreshToken())) {
                // 如果refreshToken也过期 那就直接返回登陆时间超时
                RespBean respBean = new RespBean();
                respBean.setCode(AuthEnum.TOKEN_TIMEOUT.getCode());
                respBean.setMessage(AuthEnum.TOKEN_TIMEOUT.getMsg());
                log.info("Token超时");
                return respBean;
            } else {
                // 如果refreshToken没超时就进行续签
                String claim = JWTUtils.getClaim(vo.getRefreshToken());
                // 解析token所承载的数据
                MemberVo memberVo = JSON.parseObject(claim, MemberVo.class);
                // 生成新的Token
                String accessToken = JWTUtils.createAccessToken(JSON.toJSONString(memberVo));
                String refreshToken = JWTUtils.createRefreshToken(JSON.toJSONString(memberVo));
                JwtTokenRenewalVo renewalVo = new JwtTokenRenewalVo();
                renewalVo.setAccessToken(accessToken);
                renewalVo.setRefreshToken(refreshToken);

                RespBean respBean = new RespBean();
                respBean.setCode(AuthEnum.TOKEN_RENEWAL.getCode());
                respBean.setMessage(AuthEnum.TOKEN_RENEWAL.getMsg());
                respBean.setObj(renewalVo);
                log.info("Token进行续签");
                return respBean;
            }
        } else {
            log.info("Token未超时进行荷载验证");
            // 如果没超时 开始校验荷载中的userAgent是否和该请求的UserAgent相同 如果不同那token就是被人劫持的
            // 获取荷载信息
            String claim = JWTUtils.getClaim(vo.getRefreshToken());
            // 解析token所承载的数据
            MemberVo memberVo = JSON.parseObject(claim, MemberVo.class);
            // 对比现在的请求发起方的UserAgent和登录成功后生成的荷载中的UserAgent是否相同不同就是被劫持 直接拒绝请求
            System.out.println("请求体中的荷载:"+request.getHeader("User-Agent")+" "+"token中的荷载:"+memberVo.getUserAgent());
            if (request.getHeader("User-Agent").equals(memberVo.getUserAgent())) {
                // 如果对比相同那么token验证完成 返回成功
                log.info("Token验证成功");
                return RespBean.success("token验证成功");
            } else {
                // 如果对比不一致 那么拒绝请求
                log.info("Token验证失败 用户荷载不一致");
                RespBean respBean = new RespBean();
                respBean.setCode(AuthEnum.TOKEN_USERAGENT_DISACCORD.getCode());
                respBean.setMessage(AuthEnum.TOKEN_USERAGENT_DISACCORD.getMsg());
                return respBean;
            }
        }
    }
}
